home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / v10n16.arc / PCMFAT.PAS < prev    next >
Pascal/Delphi Source File  |  1991-08-27  |  6KB  |  173 lines

  1. PROGRAM pcmfat;
  2. {*******************************************************************************
  3. *                                                                              *
  4. *              PCMFAT 1.1 Copyright (c) 1991 Barry Simon                       *
  5. *                        all rights reserved                                   *
  6. *                                                                              *
  7. *          First Published in PC Magazine, September 10, 1991                  *
  8. *                                                                              *
  9. *  Requires Turbo Pascal 6.0 to compile (because of use of inline assembler)   *
  10. *                                                                              *
  11. *******************************************************************************}
  12.   {$A-}
  13.   {the directive $A- needed StartCluster to line up}
  14. USES DOS, common;
  15.  
  16. VAR
  17.   dta : RECORD
  18.           rawdrive : Byte;
  19.           unused : ARRAY[0..25] OF Byte; {standard DTA starts at 0}
  20.           StartCluster : Word;    {to work require $A- directive!}
  21.           FSize : LongInt;
  22.         END;
  23.   FCluster : LongInt;
  24.   infcb : ARRAY[0..36] OF Byte;
  25.   regs : registers;
  26.   s : STRING;
  27.   fname : STRING[8];
  28.   fext : STRING[3];
  29.   i, j : Byte;
  30.   NumFATSec, FirstFATSec, InMemSec, CurrentSec, NumCluster : Word;
  31.   CurrentCluster, PriorCluster, RecSec, RecOff : Word;
  32.   RecShift : Boolean;             {determines if first byte is offset in 3 nibble fat}
  33.   separator : Char;
  34.   NumFrag : Byte;
  35.  
  36.   PROCEDURE SyntaxError;
  37.   BEGIN
  38.     WriteLn('  Proper syntax is:');
  39.     WriteLn('      PCMFAT <filename>');
  40.     WriteLn('  where <filename> is in the default drive and directory.');
  41.     Halt;
  42.   END;
  43.  
  44.   FUNCTION GetRec : Word;
  45.   BEGIN
  46.     IF Use3NibbleFAT THEN BEGIN
  47.       IF RecShift THEN
  48.         GetRec := (Word(Sector[RecOff]) DIV 16)+16*Word(Sector[RecOff+1])
  49.       ELSE
  50.         GetRec := Word(Sector[RecOff])+256*(Word(Sector[RecOff+1]) MOD 16);
  51.     END ELSE
  52.       GetRec := Word(Sector[RecOff])+256*Word(Sector[RecOff+1]);
  53.   END;
  54.  
  55.   PROCEDURE GetLoc;
  56.   BEGIN
  57.     IF Use3NibbleFAT THEN BEGIN
  58.       RecSec := 3*(CurrentCluster DIV 1024)+FirstFATSec;
  59.       IF RecSec > NumFATSec THEN BEGIN
  60.         WriteLn;
  61.         WriteLn('FAT error.  Please run chkdsk **without** /f. Program Halted.');
  62.         Halt;
  63.       END;
  64.       RecOff := ((3*(CurrentCluster MOD 1024)) DIV 2);
  65.       IF ((RecOff MOD 3) = 0) THEN RecShift := False ELSE RecShift := True;
  66.     END ELSE BEGIN
  67.       RecSec := Hi(CurrentCluster)+FirstFATSec;
  68.       IF RecSec > NumFATSec THEN BEGIN
  69.         WriteLn;
  70.         WriteLn('FAT error.  Please run chkdsk **without** /f. Program Halted.');
  71.         Halt;
  72.       END;
  73.       RecOff := 2*Lo(CurrentCluster);
  74.     END;
  75.   END;
  76.  
  77.   PROCEDURE GetSector;
  78.   BEGIN
  79.     CurrentSec := RecSec;
  80.     IF NOT(CurrentSec = InMemSec) THEN BEGIN
  81.       ReadSector(CurrentSec);
  82.       InMemSec := CurrentSec;
  83.     END;
  84.   END;
  85.  
  86. BEGIN
  87.   WriteLn('PC Magazine''s FAT Reader');
  88.   WriteLn('  copyright, Barrry Simon 1991');
  89.   IF ParamCount = 0 THEN SyntaxError;
  90.   s := ParamStr(1);
  91.   IF (pos('\', s)+pos(':', s)) > 0 THEN SyntaxError;
  92.   i := pos('.', s);
  93.   IF i = 0 THEN BEGIN
  94.     s := s+'.';
  95.     i := Length(s);
  96.   END;
  97.   IF i > 9 THEN SyntaxError;
  98.   fname := Copy(s, 1, i-1);
  99.   Delete(s, 1, i);
  100.   IF Length(s) > 3 THEN SyntaxError;
  101.   fext := s;
  102.   FOR j := 1 TO Length(fname) DO fname[j] := Upcase(fname[j]);
  103.   FOR j := 1 TO Length(fext) DO fext[j] := Upcase(fext[j]);
  104.   s := fname+'.'+fext;
  105.   FOR j := 1 TO (8-Length(fname)) DO fname := fname+' ';
  106.   FOR j := 1 TO (3-Length(fext)) DO fext := fext+' ';
  107.   FOR i := 1 TO 8 DO infcb[i] := Ord(fname[i]);
  108.   FOR i := 9 TO 11 DO infcb[i] := Ord(fext[i-8]);
  109.   infcb[0] := 0;                  {default drive}
  110.   WITH regs DO BEGIN
  111.     ah := $1A;                    {set DTA}
  112.     ds := Seg(dta);
  113.     dx := Ofs(dta);
  114.     msdos(regs);
  115.     ah := $11;
  116.     dx := Ofs(infcb);
  117.     ds := Seg(infcb);
  118.     msdos(regs);
  119.     IF al <> 0 THEN BEGIN
  120.       WriteLn('  ', s, ' not found');
  121.       SyntaxError;
  122.     END;
  123.   END;
  124.   DriveNum := dta.rawdrive-1;     {int 25 and service 11 differ on A=0 or 1, etc}
  125.   ReadSector(0);
  126.   IF (BootSector.BytesPerSector <> 512) THEN BEGIN
  127.     WriteLn('  The sector size isn''t 512 bytes; program halted.');
  128.     Halt;
  129.   END;
  130.   FCluster := ((dta.FSize-1) DIV (512*BootSector.SectorsPerCluster))+1;
  131.   WriteLn('  The file ', s, ' has ', FCluster, ' clusters');
  132.   WriteLn('   Starting Cluster is ',
  133.           HexWord(dta.StartCluster), ' Hex (= ', dta.StartCluster, ' decimal)');
  134.      {For display purposes, limit to files with no more than 256 clusters -
  135.        that's 512K on a typical hard disk}
  136.   IF (FCluster > 256) THEN BEGIN
  137.     WriteLn('   This program will only report detailed allotment');
  138.     WriteLn('       for files with fewer than 256 clusters.  Program halted.');
  139.     Halt;
  140.   END;
  141.   FirstFATSec := BootSector.SectorsBeforeData;
  142.   NumFATSec := BootSector.NumSecPerFAT;
  143.   asm
  144.     mov ah, $1B
  145.     push ds
  146.     Int $21
  147.     pop ds
  148.     mov NumCluster, dx
  149.   END;
  150.   Use3NibbleFAT := (NumCluster < 4097);
  151.     {Should read Partition table for totally accurate call}
  152.   CurrentCluster := dta.StartCluster;
  153.   InMemSec := 0;
  154.   NumFrag := 1;
  155.   Writeln ('   The files occupies clusters (* indicates fragments):' );
  156.   Write (' ' , HexWord(CurrentCluster));
  157.   for i := 2 to FCluster do begin
  158.   GetLoc;
  159.   GetSector;
  160.   PriorCluster := CurrentCluster;
  161.   CurrentCluster := GetRec;
  162.   If (CurrentCluster = (PriorCluster + 1)) then separator := ' ' else begin
  163.   separator := '*';
  164.   inc (NumFrag);
  165.   end;
  166.   Write (separator,HexWord (CurrentCluster));
  167.   end;
  168.   Writeln;
  169.   Writeln;
  170.   Writeln ('The file has ',NumFrag ,' fragments.');
  171. end.
  172.  
  173.